﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Data.SqlClient;
using System.Linq;
using System.Text;
using TecBaseObjects.Objects;
using TecLogger;

namespace TecData.Layer {
    internal class TecUserDataLayer : BaseSqlDataLayer {

        #region Members

        private const string checkUserIsLoggedIn = @"log.UserIsLoggedIn";
        private const string loadUserByNameStatement = @"[User].GetUserByName";
        private const string loadUserStatement = @"[User].GetUser";
        private const string saveUserLogOutStatement = @"[log].SaveUserLogout";
        private const string saveUserStatement = @"[User].SaveUser";
        private const string saveUserLoginStatement = @"[log].SaveUserLogin";
        #endregion

        #region Load

        public virtual TecUserObj LoadUser(string LoginName) {
            string sql = loadUserByNameStatement;
            using (IDataReader reader = this.GetDataReaderFromStoredProcedure(sql, new SqlParameter("@inUserName", LoginName))) {
                return (reader.Read() ? LoadUserFromDataReader(reader) : null);
            }
        }

        public virtual TecUserObj LoadUser(int UserID) {
            string sql = loadUserStatement;
            using (IDataReader reader = this.GetDataReaderFromStoredProcedure(sql, new SqlParameter("@UserID", UserID))) {
                return (reader.Read() ? LoadUserFromDataReader(reader) : null);
            }
        }

        public virtual List<TecUserObj> LoadUser() {
            return LoadUser(true);
        }

        public virtual List<TecUserObj> LoadUser(bool all) {
            string sql = loadUserStatement;
            List<TecUserObj> listUser = new List<TecUserObj>();
            using (DataTable dt = this.GetDataTableFromStoredProcedure(sql, new SqlParameter("@UserID", 0))) {
                foreach (DataRow dr in dt.Rows) {
                    bool sperre = false;
                    byte level = Convert.ToByte(dr["WorkingLevel"].ToString());
                    DateTime valid = (DateTime)dr["ValidTo"];
                    if ((int)dr["Gesperrt"] != 0) {
                        sperre = true;
                    }

                    TecUserObj u = new TecUserObj(
                        (int)dr["UserID"],
                        (string)dr["Vorname"],
                        (string)dr["Nachname"],
                        (string)dr["LoginName"],
                        sperre,
                        level,
                        valid
                        );
                    u.EMail = (string)dr["EMail"];
                    if ((u.UserID == 0 && all) || u.UserID > 0) {
                        listUser.Add(u);
                    }
                }
            }
            return listUser;
        }

        protected virtual TecUserObj LoadUserFromDataReader(IDataReader reader) {
            TecUserObj u = new TecUserObj(this.GetInt32(reader, "UserID"),
                                        this.GetString(reader, "Vorname"),
                                        this.GetString(reader, "Nachname"),
                                        this.GetString(reader, "LoginName"),
                                        this.GetBoolean(reader, "Gesperrt"),
                                        this.GetByte(reader, "WorkingLevel"),
                                        this.GetDateTime(reader, "ValidTo")
                                        );
            u.EMail = this.GetString(reader, "EMail");
            u.LoginTime = DateTime.Now;
            return u;
        }

        #endregion

        #region Save

        public virtual void SaveTecUser(TecUserObj u) {
            SqlParameter[] parameters = GetParameters(u);
            int ret = ExecuteStoredProcedure(saveUserStatement, parameters);
            if (ret == 0) {
                //log.Add("SaveTecUser: ExecuteStoredProcedure = 0", true);
            }
        }

        public virtual void SaveUserLogin(int userID, DateTime loginTime, string pcName) {
            try {
                int ret = ExecuteStoredProcedure(saveUserLoginStatement,    new SqlParameter("@UserID", userID), 
                                                                            new SqlParameter("@LoginTime", loginTime),
                                                                            new SqlParameter("@PcName", pcName));
            } finally {
                //toDo: log in file

            }
        }

        public virtual void SaveUserLogout(int userID) {
            try {
                int ret = ExecuteStoredProcedure(saveUserLogOutStatement, new SqlParameter("@UserID", userID));
            } finally {
                //toDo: log in file
                
            }
        }

        #endregion

        #region Functions

        public virtual bool CheckUserIsLoggedIn(int userID) {
            bool ret = false;
            string sql = checkUserIsLoggedIn;
            using (IDataReader reader = this.GetDataReaderFromStoredProcedure(sql, new SqlParameter("@UserID", userID))) {
                if (reader.Read()) {
                    ret = this.GetBoolean(reader, "LoggedIn");
                }
            }
            return ret;
        }

        protected virtual SqlParameter[] GetParameters(TecUserObj u) {
            SqlParameter[] ps = new SqlParameter[7];

            ps[0] = new SqlParameter("@UserID", u.UserID);
            ps[1] = new SqlParameter("@Vorname", u.Vorname);
            ps[2] = new SqlParameter("@Nachname", u.Nachname);
            ps[3] = new SqlParameter("@LoginName", u.LoginName);
            ps[4] = new SqlParameter("@Gesperrt", u.Gesperrt);
            ps[5] = new SqlParameter("@WorkingLevel", u.WorkingLevel);
            ps[6] = new SqlParameter("@ValidTo", u.ValidTo);

            return ps;

        }

        

        #endregion

    }
}
